From 1b7e15f112382a3c5028bda9d73627e30bfa6ad1 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 5 Apr 2006 10:37:37 +0100 Subject: [PATCH] Fix checksum-offload problems introduced in c/s 9514, due to data_validated flag not being properly specified on the device channel. Signed-off-by: Keir Fraser --- .../drivers/xen/netback/netback.c | 12 ++++++++---- .../drivers/xen/netfront/netfront.c | 19 +++++++++++++------ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c index d9f259ce26..8e3a1c72b7 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -329,9 +329,9 @@ static void net_rx_action(unsigned long unused) irq = netif->irq; id = RING_GET_REQUEST(&netif->rx, netif->rx.rsp_prod_pvt)->id; flags = 0; - if (skb->ip_summed == CHECKSUM_HW) - flags |= NETRXF_csum_blank; - if (skb->proto_data_valid) + if (skb->ip_summed == CHECKSUM_HW) /* local packet? */ + flags |= NETRXF_csum_blank | NETRXF_data_validated; + else if (skb->proto_data_valid) /* remote but checksummed? */ flags |= NETRXF_data_validated; if (make_rx_response(netif, id, status, (unsigned long)skb->data & ~PAGE_MASK, @@ -658,7 +658,11 @@ static void net_tx_action(unsigned long unused) skb->dev = netif->dev; skb->protocol = eth_type_trans(skb, skb->dev); - if (txreq.flags & NETTXF_data_validated) { + /* + * Old frontends do not assert data_validated but we + * can infer it from csum_blank so test both flags. + */ + if (txreq.flags & (NETTXF_data_validated|NETTXF_csum_blank)) { skb->ip_summed = CHECKSUM_UNNECESSARY; skb->proto_data_valid = 1; } else { diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index 1f2ee99e58..b85ff4b1d3 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -698,9 +698,9 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) tx->size = skb->len; tx->flags = 0; - if (skb->ip_summed == CHECKSUM_HW) - tx->flags |= NETTXF_csum_blank; - if (skb->proto_data_valid) + if (skb->ip_summed == CHECKSUM_HW) /* local packet? */ + tx->flags |= NETTXF_csum_blank | NETTXF_data_validated; + if (skb->proto_data_valid) /* remote but checksummed? */ tx->flags |= NETTXF_data_validated; np->tx.req_prod_pvt = i + 1; @@ -816,7 +816,11 @@ static int netif_poll(struct net_device *dev, int *pbudget) skb->len = rx->status; skb->tail = skb->data + skb->len; - if (rx->flags & NETRXF_data_validated) { + /* + * Old backends do not assert data_validated but we + * can infer it from csum_blank so test both flags. + */ + if (rx->flags & (NETRXF_data_validated|NETRXF_csum_blank)) { skb->ip_summed = CHECKSUM_UNNECESSARY; skb->proto_data_valid = 1; } else { @@ -1017,8 +1021,11 @@ static void network_connect(struct net_device *dev) tx->gref = np->grant_tx_ref[i]; tx->offset = (unsigned long)skb->data & ~PAGE_MASK; tx->size = skb->len; - tx->flags = (skb->ip_summed == CHECKSUM_HW) ? - NETTXF_csum_blank : 0; + tx->flags = 0; + if (skb->ip_summed == CHECKSUM_HW) /* local packet? */ + tx->flags |= NETTXF_csum_blank | NETTXF_data_validated; + if (skb->proto_data_valid) /* remote but checksummed? */ + tx->flags |= NETTXF_data_validated; np->stats.tx_bytes += skb->len; np->stats.tx_packets++; -- 2.30.2